package com.ruoyi.trainingManagement.controller;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.trainingManagement.domain.CourseScheduleDetails;
import com.ruoyi.trainingManagement.domain.CourseStudentInfo;
import com.ruoyi.trainingManagement.domain.Vo.ScoreConfigDTO;
import com.ruoyi.trainingManagement.domain.Vo.StudentScoreVo;
import com.ruoyi.trainingManagement.mapper.CourseScheduleDetailsMapper;
import com.ruoyi.trainingManagement.service.ICourseStudentGradeInputService;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import com.alibaba.fastjson.JSON; // 必须导入Fastjson的JSON类
import org.springframework.web.multipart.MultipartFile;


import static com.ruoyi.framework.datasource.DynamicDataSourceContextHolder.log;

/**
 * 成绩录入专用控制器（纯MyBatis）
 */
@RestController
@RequestMapping("/training/grade-input")
public class GradeInputController {

    @Resource
    private ICourseStudentGradeInputService gradeInputService;
    @Resource
    private CourseScheduleDetailsMapper courseScheduleDetailsMapper;



    /**
     * 分步导入：接收文件→解析→入库（每步日志）
     */
    // 关键：添加consumes = MediaType.MULTIPART_FORM_DATA_VALUE
    @PostMapping(
            value = "/import",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE // 强制要求multipart/form-data
    )
    public AjaxResult importScoreStepByStep(
            @RequestParam("file") MultipartFile file,
            @RequestParam("courseScheduleDetailsId") String courseScheduleDetailsId
    ) {
        // 第一步：接收文件，打印基础信息（确认请求到达）
        log.info("==== 后端：第一步 - 接收导入请求 ====");
        log.info("课程班ID：{}", courseScheduleDetailsId);
        log.info("接收文件信息：文件名={}, 大小={}KB, 类型={}",
                file.getOriginalFilename(),
                file.getSize() / 1024,
                file.getContentType());

        try {
            // 校验文件是否为空
            if (file.isEmpty()) {
                log.error("后端：第一步失败 - 文件为空");
                return AjaxResult.error("导入失败：请选择非空的Excel文件");
            }

            // 第二步：调用Service解析Excel（单独方法，便于排查）
            log.info("==== 后端：第二步 - 开始解析Excel文件 ====");
            List<CourseStudentInfo> studentScoreList = gradeInputService.parseExcelFile(file, courseScheduleDetailsId);
            log.info("后端：第二步成功 - 解析出{}条学生成绩数据", studentScoreList.size());

            // 第三步：调用Service批量入库（复用原有逻辑，增加日志）
            log.info("==== 后端：第三步 - 开始批量入库 ====");
            int successCount = gradeInputService.batchSubmitGradeInputScores(studentScoreList);
            int failCount = studentScoreList.size() - successCount;
            log.info("后端：第三步完成 - 入库成功{}条，失败{}条", successCount, failCount);

            // 第四步：组装结果（包含失败原因）
            log.info("==== 后端：第四步 - 准备返回导入结果 ====");
            return AjaxResult.success("导入完成", new HashMap<String, Object>() {{
                put("successCount", successCount);
                put("failCount", failCount);
                put("failReasons", gradeInputService.getBatchFailReasons()); // 失败详情
            }});

        } catch (Exception e) {
            // 捕获所有异常，打印详细日志
            log.error("后端：导入流程异常中断", e);
            return AjaxResult.error("导入失败：" + e.getMessage());
        }
    }





    @GetMapping("/students/{courseScheduleDetailsId}")
    public AjaxResult getEnrolledStudents(@PathVariable String courseScheduleDetailsId) {
        System.out.println("接收的courseScheduleDetailsId：" + courseScheduleDetailsId);
        List<StudentScoreVo> students = gradeInputService.selectEnrolledGradeInputStudents(courseScheduleDetailsId);

        return AjaxResult.success(students);
    }

    @PostMapping("/submit")
    public AjaxResult submitScore(@RequestBody CourseStudentInfo info) {
        boolean success = gradeInputService.submitGradeInputScore(info);
        return success ? AjaxResult.success("成绩提交成功") : AjaxResult.error("提交失败");
    }

    @PostMapping("/batch-submit")
    public AjaxResult batchSubmit(@RequestBody List<CourseStudentInfo> infos) {
        int successCount = gradeInputService.batchSubmitGradeInputScores(infos);
        return AjaxResult.success("批量提交完成，成功" + successCount + "条，失败" + (infos.size() - successCount) + "条");
    }
//    @PostMapping("/config/save")
//    public AjaxResult saveScoreConfig(@RequestBody ScoreConfigDTO dto) {
//        CourseScheduleDetails schedule = courseScheduleDetailsMapper.selectById(dto.getCourseId());
//        schedule.setScoreConfig(dto.getConfig());
//        courseScheduleDetailsMapper.updateById(schedule);
//        return AjaxResult.success();
//    }
//
//    @GetMapping("/config/{courseId}")
//    public AjaxResult getScoreConfig(@PathVariable String courseId) {
//        CourseScheduleDetails schedule = courseScheduleDetailsMapper.selectById(courseId);
//        return AjaxResult.success(schedule.getScoreConfig() != null ? JSON.parse(schedule.getScoreConfig()) : null);
//    }
// 保存配置接口（修正后）
@PostMapping("/config/save")
public AjaxResult saveScoreConfig(@RequestBody ScoreConfigDTO dto) {
    // 1. 校验课程班是否存在
    CourseScheduleDetails schedule = courseScheduleDetailsMapper.selectById(dto.getCourseId());
    if (schedule == null) {
        return AjaxResult.error("课程班不存在");
    }
    // 2. 更新成绩配置
    schedule.setScoreConfig(dto.getConfig());
    int rows = courseScheduleDetailsMapper.updateById(schedule); // 现在不会爆红
    return rows > 0 ? AjaxResult.success("配置保存成功") : AjaxResult.error("保存失败");
}

    // 获取配置接口（修正后）
    @GetMapping("/config/{courseId}")
    public AjaxResult getScoreConfig(@PathVariable String courseId) {
        CourseScheduleDetails schedule = courseScheduleDetailsMapper.selectById(courseId);
        if (schedule == null) {
            return AjaxResult.error("课程班不存在");
        }
        String scoreConfig = schedule.getScoreConfig();
        if (scoreConfig == null) {
            return AjaxResult.success(null); // 无配置时返回null
        }
        // 解析JSON并处理格式错误
        try {
            return AjaxResult.success(JSON.parse(scoreConfig)); // 现在不会爆红
        } catch (Exception e) {
            log.error("配置解析失败: {}", e.getMessage());
            return AjaxResult.error("配置格式错误，请重新设置");
        }
    }

//=========================================8.12
    /**
     * 导出所有学生成绩（手动定义表头和字段）
     */
    @Log(title = "成绩管理", businessType = BusinessType.EXPORT)
    @GetMapping("/export-all/{courseScheduleDetailsId}")
    public void exportAllStudents(
            @PathVariable String courseScheduleDetailsId,
            HttpServletResponse response
    ) throws Exception {
        // 1. 查询数据
        List<StudentScoreVo> dataList = gradeInputService.selectEnrolledGradeInputStudents(courseScheduleDetailsId);
        if (dataList.isEmpty()) {
            response.getWriter().write("没有可导出的数据");
            return;
        }

        // 2. 创建Excel
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("学生成绩列表");

        // 3. 手动定义表头（直接对应需要导出的字段）
        String[] headers = {
                "学号", "学生姓名", "平时成绩", "期末成绩",
                "实验成绩", "期中成绩", "课程设计成绩", "其他成绩",
                "总成绩", "绩点"
        };
        XSSFRow headerRow = sheet.createRow(0);
        for (int i = 0; i < headers.length; i++) {
            headerRow.createCell(i).setCellValue(headers[i]);
        }

        // 4. 手动填充数据（直接调用getter方法，无需反射）
        for (int rowIdx = 0; rowIdx < dataList.size(); rowIdx++) {
            StudentScoreVo student = dataList.get(rowIdx);
            XSSFRow dataRow = sheet.createRow(rowIdx + 1);

            // 按表头顺序填充字段，处理BigDecimal保留1位小数
            dataRow.createCell(0).setCellValue(student.getStudentNo()); // 学号
            dataRow.createCell(1).setCellValue(student.getStudentName()); // 姓名
            dataRow.createCell(2).setCellValue(getBigDecimalValue(student.getRegularScore())); // 平时成绩
            dataRow.createCell(3).setCellValue(getBigDecimalValue(student.getFinalScore())); // 期末成绩
            dataRow.createCell(4).setCellValue(getBigDecimalValue(student.getExperimentScore())); // 实验成绩
            dataRow.createCell(5).setCellValue(getBigDecimalValue(student.getMidtermScore())); // 期中成绩
            dataRow.createCell(6).setCellValue(getBigDecimalValue(student.getCourseDesignScore())); // 课程设计成绩
            dataRow.createCell(7).setCellValue(getBigDecimalValue(student.getOtherScore())); // 其他成绩
            dataRow.createCell(8).setCellValue(getBigDecimalValue(student.getTotalScore())); // 总成绩
            dataRow.createCell(9).setCellValue(getBigDecimalValue(student.getGradePoint())); // 绩点
        }

        // 5. 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }

        // 6. 响应下载
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("UTF-8");
        String fileName = URLEncoder.encode("学生成绩表", StandardCharsets.UTF_8.name());
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + ".xlsx\"");

        // 7. 写入流并清理
        ServletOutputStream outputStream = response.getOutputStream();
        workbook.write(outputStream);
        outputStream.flush();
        outputStream.close();
        workbook.close();
    }

    /**
     * 处理BigDecimal值，保留1位小数（空值返回0）
     */
    private double getBigDecimalValue(BigDecimal value) {
        if (value == null) {
            return 0.0;
        }
        return value.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
    }






}